<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>使用WebGL绘制一个矩形</title>
  </head>
  <body>
    <canvas
      id="webgl"
      width="500"
      height="500"
      style="background-color: blue"
    ></canvas>
    <!-- 着色器语法，;分号要加上,括号外不要加 -->
    <!-- 顶点着色器源码 -->
    <script id="vertexShader" type="x-shader/x-vertex">
      // attribute声明vec4类型变量 apos
      // x,y,z,w(齐次坐标)
      attribute vec4 apos;
      void main() {
        //给内置变量gl_PointSize赋值像素大小
        gl_PointSize=40.0;
        //顶点位置，位于坐标原点
        gl_Position = apos;
      }
    </script>
    <!-- 片元着色器源码 -->
    <!-- rgba -->
    <script id="fragmentShader" type="x-shader/x-fragment">
      void main() {
        gl_FragColor = vec4(1.0,0.0,0.0,1.0);
      }
    </script>
  </body>
  <script>
    // 通过getElementById()获取canvas 画布
    const canvas = document.getElementById('webgl')
    // 通过方法getContext()h获取WebGL上下文
    /** @type {WebGLRenderingContext} */
    let gl = canvas.getContext('webgl')

    /** @param {!WebGLRenderingContext} gl */
    const initShader = (gl, vertexShaderSource, fragShaderSource) => {
      // 创建顶点着色器对象
      let vertexShader = gl.createShader(gl.VERTEX_SHADER)
      // 创建片元着色器对象
      let fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)

      // 引入顶点、片元着色器源代码
      gl.shaderSource(vertexShader, vertexShaderSource)
      gl.shaderSource(fragmentShader, fragShaderSource)

      // 编译顶点、片元着色器
      gl.compileShader(vertexShader)
      gl.compileShader(fragmentShader)

      // 创建程序对象program
      let program = gl.createProgram()
      // 附着顶点着色器和片元着色器到program
      gl.attachShader(program, vertexShader)
      gl.attachShader(program, fragmentShader)

      // 链接program
      gl.linkProgram(program)

      // 使用program
      gl.useProgram(program)

      return program
    }

    //顶点着色器源码
    let vertexShaderSource = document.getElementById('vertexShader').innerText
    //片元着色器源码
    let fragShaderSource = document.getElementById('fragmentShader').innerText
    // 初始化着色器
    let program = initShader(gl, vertexShaderSource, fragShaderSource)

    // apos 为着色器中定义的变量
    let aposLocation = gl.getAttribLocation(program, 'apos')

    // 类型数组构造函数Float32Array创建顶点数组
    // 每两个代表下x,y,一个点的坐标
    let data = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5])

    // 创建缓冲区对象
    let buffer = gl.createBuffer()
    // 绑定缓冲区对象
    gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
    // 将顶点数组data传入缓冲区
    gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW)
    //缓冲区中的数据按照一定的规律传递给位置变量apos
    // 2个一传，虽然虽然内部vec4 需要4个数据，后面两个z默认为0,w默认为1
    gl.vertexAttribPointer(aposLocation, 2, gl.FLOAT, false, 0, 0)
    //允许数据传递
    gl.enableVertexAttribArray(aposLocation)
    //开始绘制图形 线条模式
    gl.drawArrays(gl.LINE_LOOP, 0, 4)
  </script>
</html>
